package com.kaifamiao.wendao.dao;

import com.kaifamiao.wendao.entity.Customer;
import org.apache.commons.dbutils.ResultSetHandler;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class CustomerDao extends BaseDao<Customer,Long> {

    private static final String SELECT_BASE="select id, username, password, salt, nickname, reg_date from t_customers";
    public final static String SELECT_ONE = SELECT_BASE +" where id = ?";
    public final static String SELECT_NAME = SELECT_BASE +" where username = ?";
    private static final String SELECT_ALL = SELECT_BASE + " order by id ";
    public final static String SELECT_MAX_ID ="select max(id) from t_customers";
    public final static String INSERT_ONE = "insert into t_customers (username,password,salt,nickname,reg_date,id) values (?,?,?,?,?,?)";
    private static final String UPDATE_ONE = " update t_customers set username=?,password=?, salt=?,nickname=? where id=?";
    private final static String DELETE_ONE = "delete from t_customers where id = ?";

    public Customer wrap(ResultSet rs) throws SQLException{
        Customer c= new Customer();
        c.setId(rs.getLong("id"));
        c.setUsername(rs.getString("username"));
        c.setPassword(rs.getString("password"));
        c.setSalt(rs.getString("salt"));
        c.setNickname(rs.getString("nickname"));
        java.sql.Date date= rs.getDate("reg_date");
        LocalDate regDate = date == null ? null : date.toLocalDate();
        c.setRegisterDate(regDate);
        return c;
    }
    @Override
    public boolean save(Customer customer) {
        LocalDate date = customer.getRegisterDate();
        java.sql.Date regDate = date ==null ? null : Date.valueOf(date);
        Object[] param = {customer.getUsername(),customer.getPassword(), customer.getSalt(), customer.getNickname(),regDate,customer.getId()};
        try {
            return runner.update(INSERT_ONE,param)==1;
        } catch (SQLException cause) {
            throw new RuntimeException("插入失败",cause);
        }
    }

    @Override
    public boolean update(Customer customer) {
        Object[] params = {customer.getUsername(),customer.getPassword(),customer.getSalt(),customer.getNickname(), customer.getId()};
        try {
            return runner.update(UPDATE_ONE,params)==1;
        } catch (SQLException cause) {
            throw new RuntimeException("更新失败",cause);
        }
    }

    @Override
    public boolean remove(Long id) {
        try {
            return runner.update(DELETE_ONE,id)!=1;
        } catch (SQLException cause) {
            throw new RuntimeException("删除失败",cause);
        }
    }

    @Override
    public List<Customer> findAll() {
        ResultSetHandler<List<Customer>> rsHandler = rs -> {
            List<Customer> list= new ArrayList<>();
            while (rs.next()){
                Customer c = wrap(rs);
                list.add(c);
            }
            return list;
        };
        try {
            return runner.query(SELECT_ALL,rsHandler);
        } catch (SQLException cause) {
            throw new RuntimeException("查询失败",cause);
        }
    }

    @Override
    public Customer find(Long id) {
        ResultSetHandler<Customer> rsHandler =rs -> {
            if (rs.next()){
                Customer c=wrap(rs);
                return c;
            }
            return null;
        };
        try {
            return runner.query(SELECT_ONE,rsHandler,id);
        } catch (SQLException cause) {
            throw new RuntimeException("查询失败",cause);
        }
    }

    /**
     * 检查指定用户名在数据库表中是否已经存在
     * @param username 待检查用户名
     * @return 仅当用户名已经存在于数据库中时返回 true ；否则，返回 false 。
     */
    public boolean find(String username) {

        try {
            return runner.query(SELECT_NAME, rs -> rs.next(),username);
        } catch (SQLException cause) {
            throw new RuntimeException("查询失败",cause);
        }
    }

    /**
     * 根据用户名查询单个用户
     * @param username 待查询用户名
     * @return 指定用户名对应的Customer对象
     */
    public Customer findName(String username){
        ResultSetHandler<Customer> rsHandler =rs -> {
            if (rs.next()){
                Customer c=wrap(rs);
                return c;
            }
            return null;
        };
        try {
            return runner.query(SELECT_NAME,rsHandler,username);
        } catch (SQLException cause) {
            throw new RuntimeException("查询失败",cause);
        }
    }
}
